#ifndef GL_SHOWLIST_MANAGER_H
#define GL_SHOWLIST_MANAGER_H
#include <vector>
#include <string>
#include <ooputils/Singleton.hpp>
#include <ooputils/OOPException.hpp>
#include "OOPGl_BaseGlobal.hpp"

_GLBASE_BEGIN

class ShowlistManagerException : public OOPUtils::OOPException
{
public:

	virtual OOPUtils::OOPString getReason () const throw ()
	{
		return L"Unknown showlist manager exception.";
	}
};

class ShowlistFullException : public ShowlistManagerException
{
public:

	virtual OOPUtils::OOPString getReason () const throw ()
	{
		return L"Too many showlists! You can only have 65535 show lists.";
	}
};

class ShowlistNotFoundException : public ShowlistFullException
{
public:

	virtual OOPUtils::OOPString getReason () const throw ()
	{
		return L"Show list of the specified name is not found";
	}
};

class _EXPORT_GLBASE_CLASS GlShowlistManager : public OOPUtils::Singleton< GlShowlistManager >
{
	friend class OOPUtils::Singleton< GlShowlistManager >;

private:

	struct ShowListInfo { unsigned int nextFree; std::string name; };
	std::vector< ShowListInfo > _showListContainer;

	GlShowlistManager ();
	~GlShowlistManager ();

public:

  //************************************
  // Method:  ShowListManager::createNewList
  // Parameter: std::string name - Name for this new show list
  // Parameter: unsigned int mode - The compilation mode
  //
  // Create a new opengl show list. The compilation mode can be
  // GL_COMPILE or GL_COMPILE_AND_EXECUTE, as opengl specified.
  // You should call glEndList () after complete the definition of the
  // show list.
  //************************************
  void createNewList (std::string name, unsigned int mode) throw (ShowlistFullException &);

  //************************************
  // Method:  ShowListManager::getList
  // Returns:   unsigned int - The id of related show list
  // Parameter: std::string name - The name of the show list to get
  //
  // Get the id of the show list related to the name specified.
  // Then you can call glCallList () to call this show list.
  //************************************
  unsigned int getList (std::string name) throw (ShowlistNotFoundException &);

  //************************************
  // Method:    ShowListManager::deleteList
  // Parameter: std::string name - The name of the show list to delete
  //
  // Delete the show list related to the name specified and free its space.
  //************************************
  void deleteList (std::string name);
};

_GLBASE_END

#endif